package top.xia17.plugins.fast.auth.rest;

import cn.hutool.core.bean.BeanUtil;
import top.xia17.plugins.fast.common.model.Back;
import top.xia17.plugins.fast.common.security.SecUtil;
import top.xia17.plugins.fast.common.security.anonymous.AnonymousGetMapping;
import top.xia17.plugins.fast.common.security.anonymous.AnonymousPostMapping;
import top.xia17.plugins.fast.common.security.base.LoginInfo;
import top.xia17.plugins.fast.common.security.token.provider.TokenProvider;
import top.xia17.plugins.fast.common.utils.web.RequestUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import top.xia17.plugins.fast.auth.autoconfiguraion.AuthProperties;
import top.xia17.plugins.fast.auth.login.EmailLoginHelper;
import top.xia17.plugins.fast.auth.login.UsernameLoginHelper;
import top.xia17.plugins.fast.auth.model.req.EmailLoginCodeReq;
import top.xia17.plugins.fast.auth.model.req.EmailLoginReq;
import top.xia17.plugins.fast.auth.model.req.UsernameLoginReq;
import top.xia17.plugins.fast.auth.model.resp.LoginResp;
import top.xia17.plugins.fast.user.model.dto.RoleDto;
import top.xia17.plugins.fast.user.model.resp.MenuVo;
import top.xia17.plugins.fast.user.service.MenuService;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 授权相关接口
 *
 * @author xia17
 * @date 2022/2/18
 */
@RestController
@RequestMapping("auth")
@RequiredArgsConstructor
@Slf4j
public class AuthRest {

    private final TokenProvider tokenProvider;
    private final MenuService menuService;
    private final AuthProperties authProperties;
    private final UsernameLoginHelper usernameLoginHelper;
    private final EmailLoginHelper emailLoginHelper;

    /**
     * 用户名密码登录
     *
     * @param req      /
     * @param response /
     * @return /
     */
    @AnonymousPostMapping("login/username")
    public Back<LoginResp> loginUsername(@Valid @RequestBody UsernameLoginReq req, HttpServletResponse response) {
        LoginResp loginResp = this.usernameLoginHelper.login(req, response);
        return Back.ok(loginResp);
    }

    /**
     * 邮箱验证码登录
     *
     * @param req      请求信息
     * @param response /
     * @return /
     */
    @AnonymousPostMapping("login/email")
    public Back<LoginResp> loginEmail(@Valid @RequestBody EmailLoginReq req, HttpServletResponse response) {
        LoginResp loginResp = emailLoginHelper.login(req, response);
        return Back.ok(loginResp);
    }

    /**
     * 发送邮箱登录时的安全码
     *
     * @param req 邮箱号
     * @param request /
     * @return 返回uuid
     */
    @AnonymousPostMapping("login/email/code")
    public Back<String> sendEmailLoginCode(@RequestBody EmailLoginCodeReq req , HttpServletRequest request){
        String uuid = emailLoginHelper.sendEmailCode(req.getEmail(), RequestUtil.getIp(request));
        return Back.okStr(uuid);
    }


    /**
     * 退出登录
     *
     * @return /
     */
    @GetMapping("logout")
    public Back<String> logout() {
        tokenProvider.removeToken(SecUtil.getToken());
        return Back.ok();
    }


    /**
     * 当前登录信息
     *
     * @return /
     */
    @GetMapping("info")
    public Back<LoginInfo> info() {
        LoginInfo loginInfo = SecUtil.getLoginInfo();
        return Back.ok(loginInfo);
    }


    /**
     * 当前登录的用户权限信息
     *
     * @return /
     */
    @GetMapping("permissions")
    public Back<List<String>> permissions() {
        List<String> authorityList = SecUtil.getAuthorityList();
        return Back.ok(authorityList);
    }


    /**
     * 获取当前登录的用户菜单
     *
     * @return /
     */
    @GetMapping("menus")
    public Back<List<MenuVo>> menus(Boolean mobile) {
        if (mobile == null) {
            mobile = false;
        }
        Collection<Object> roles = SecUtil.getLoginInfo().getRoles();
        // roles 转换成 roleIds
        List<Long> roleIds = roles.stream()
                .map(e -> ((RoleDto) e).getId())
                .collect(Collectors.toList());
        // 查询数据
        List<MenuVo> list = menuService.getMenuTreeByRoles(roleIds, mobile);
        return Back.ok(list);
    }

    /**
     * 获取认证配置信息
     * @return /
     */
    @AnonymousGetMapping("get_auth_properties")
    public Back<AuthProperties> getAuthProperties(){
        AuthProperties res = new AuthProperties();
        BeanUtil.copyProperties(this.authProperties,res,false);
        return Back.ok(res);
    }



}
